package demo.TCPtest;

import java.io.BufferedReader;  
import java.io.DataInputStream;  
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;  
import java.net.ServerSocket;  
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

public class TCPServer {
    public static final int PORT = 12345;//监听的端口号     
    public static final String directory = "Z:\\低保真原型图";
    public static Map<String,String> map = new HashMap<String,String>();
      
    public static void main(String[] args) {
        System.out.println("服务器启动...\n");
        TCPServer server = new TCPServer();
        server.init();
    }    
    
    public void init() {
        try {    
            ServerSocket serverSocket = new ServerSocket(PORT);
            while (true) {    
                // 一旦有堵塞, 则表示服务器与客户端获得了连接    
                Socket client = serverSocket.accept();
                map = new HashMap<String,String>();
                FilesDirHelper.buildMap(directory,"",map);
                // 处理这次连接    
                new HandlerThread(client);
            }    
        } catch (Exception e) {    
            System.out.println("服务器异常: " + e.getMessage());
        }    
    }    
    
    private class HandlerThread implements Runnable {    
    	Logger logger = LoggerFactory.getLogger(HandlerThread.class);
        private Socket socket;
        public HandlerThread(Socket client) {    
            socket = client;
            new Thread(this).start();
        }    
    
        public void run() {    
            try {    
                // 读取客户端数据    
                DataInputStream input = new DataInputStream(socket.getInputStream());  
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                
                String clientInputStr = input.readUTF();//这里要注意和客户端输出流的写方法对应,否则会抛 EOFException  
                // 处理客户端数据    
                logger.debug("客户端发过来的内容:" + clientInputStr);
                //对比双方文件夹
                HashMap clientMap = JSON.parseObject(clientInputStr, HashMap.class);
                String str = JSON.toJSONString(map);
                logger.debug("服务端的内容:" + str);
                Map<String,String> cMap = FilesDirHelper.comparisonDirMap(map, clientMap);
                
                for(Entry<String, String> entry :cMap.entrySet())
        		{
                	// 向客户端回复信息    
                    out.writeUTF(entry.getKey());
                    out.writeUTF(entry.getValue());
                    logger.debug("开始发送文件:"+entry.getKey());
                    File f = new File(directory+entry.getKey());
                    //开始传递文件
                    InputStream ins = new FileInputStream(f);

                    logger.debug("长度："+f.length());
                    //等待客户端准备完成
                    String value = input.readUTF();
                    logger.debug("客户端消息："+value);
                    //TODO 判断客户端返回值  判不判断关系貌似不大，这里可以做个验证
                    //缓冲区大小  默认1000
                    int tempLength = 1000;
                    for(int i=0;i<=(f.length()/tempLength);i++){
                        byte[] buffer = new byte[tempLength];
                        //判断文件是否到达末尾,如果到达末尾,则使用最后尾数的大小
                        if(i==f.length()/tempLength){
                            buffer = new byte[(int)(f.length()%tempLength)];
                        }
                        ins.read(buffer);
                    	out.writeInt(buffer.length);
                    	logger.debug("长度："+buffer.length);
        	            out.write(buffer);
        	            //logger.debug(FilesDirHelper.print(buffer));
        	            byte[] buffer1 = new byte[1000];
                        input.read(buffer1);
                        if(!FilesDirHelper.compare(buffer,buffer1)){
                            System.out.println(FilesDirHelper.print(buffer));
                            System.out.println(FilesDirHelper.print(buffer1));
                        }
        	        }
                    out.writeInt(0);
                    ins.close();
                    String clientInputStr2 = input.readUTF();
                    logger.debug("客户端发过来的内容:" + clientInputStr2);
                    logger.debug(entry.getKey()+"end");
                    Thread.sleep(1000);
                }
                
                //完成则返回 ok & end
                out.writeUTF("ok");
                out.writeUTF("end");
                logger.debug("end");

                out.close();
                input.close();
            } catch (Exception e) {    
                System.out.println("服务器 run 异常: " + e.getMessage());
            } finally {    
                if (socket != null) {    
                    try {    
                        socket.close();
                    } catch (Exception e) {    
                        socket = null;
                        System.out.println("服务端 finally 异常:" + e.getMessage());
                    }    
                }    
            }   
        }    
    }    
}    